package com.xinhua.erp.service;

import com.xinhua.erp.pojo.Account;
import com.xinhua.erp.pojo.PageResult;
import com.xinhua.erp.pojo.Result;
import com.xinhua.erp.pojo.Supplier;
import com.xinhua.erp.repo.AccountRepo;
import com.xinhua.erp.utils.IdWorker;
import com.xinhua.erp.utils.OrderNumber;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Map;

@Service
@Transactional
public class AccountService {

    @Autowired
    private AccountRepo accountRepo;

    @Autowired
    private IdWorker idWorker;

    public Result findAll(){
        return Result.OK(accountRepo.findAll());
    }


    public Result findById(long id){

        return Result.OK(accountRepo.getOne(id));
    }

   public Result findAll(int page,int size){

        Pageable pageable = PageRequest.of(page - 1, size);

        Page<Account> accounts = accountRepo.findAll(pageable);

        return Result.OK(new PageResult<>(accounts.getTotalElements(),accounts.getContent()));
    }




    public Result deleteById(long id){

        accountRepo.deleteById(id);

        return Result.OK();
    }

    public Result save(Account account){

        account.setId(idWorker.nextId());

        //设置默认值
        account.setSerialno(OrderNumber.getAccount());

        account.setCurrentAccountBalance(account.getInitAccountBalance());

        accountRepo.save(account);

        return Result.OK();
    }

    public Result update(Long id,Account account){
        account.setId(id);
        accountRepo.save(account);
        return Result.OK();
    }

    public Result Search(Map searchMap, int page, int size) {

        Pageable pageable = PageRequest.of(page - 1, size);

        Page<Account> accounts = accountRepo.findAll(createSpecification(searchMap), pageable);

        return Result.OK(new PageResult<>(accounts.getTotalElements(), accounts.getContent()));
    }

    private Specification<Account> createSpecification(Map searchMap){
        return new Specification<Account>() {
            @Override
            public Predicate toPredicate(Root<Account> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                ArrayList<Predicate> predicateList = new ArrayList<>();

                if(!StringUtils.isBlank((String)searchMap.get("name"))){
                    predicateList.add(criteriaBuilder.like(root.get("name").as(String.class),"%"+searchMap.get("name")+"%"));
                }

                if(!StringUtils.isBlank((String)searchMap.get("serialno"))){
                    predicateList.add(criteriaBuilder.like(root.get("serialno").as(String.class),"%"+searchMap.get("serialno")+"%"));
                }

                return criteriaBuilder.and(predicateList.toArray(new Predicate[predicateList.size()]));
            }
        };
    }
}
